package indi.caibo.service_edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import indi.caibo.service_edu.entity.EduComment;
import indi.caibo.service_edu.entity.EduCourse;
import indi.caibo.service_edu.entity.EduCourseDescription;
import indi.caibo.service_edu.entity.vo.course.CourseInfoVo;
import indi.caibo.service_edu.entity.vo.course.CoursePublishVo;
import indi.caibo.service_edu.entity.vo.course.CourseQueryVo;
import indi.caibo.service_edu.entity.vo.course.CourseFrontVo;
import indi.caibo.service_edu.mapper.EduCourseMapper;
import indi.caibo.service_edu.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import indi.caibo.servicebase.exceptionhandler.GuliException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author Bo Cai
 * @since 2021-10-07
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
    @Autowired
    private EduCourseDescriptionService courseDescriptionService;
    @Autowired
    EduChapterService chapterService;
    @Autowired
    EduVideoService videoService;
    @Autowired
    EduSubjectServiceImpl subjectService;
    @Autowired
    EduCommentService commentService;
    @Autowired
    EduCourseCollectService courseCollectService;

    @Override
    public String saveCourseInfo(CourseInfoVo courseInfoVo) {
        /*1. 保存课程信息*/
        EduCourse course = new EduCourse();
        course.setStatus(EduCourse.COURSE_DRAFT); // 课程状态设置为未发布
        BeanUtils.copyProperties(courseInfoVo, course);
        /*1.1 获取课程分类父id的信息并且设置*/
        String parentId = subjectService.getById(courseInfoVo.getSubjectId()).getParentId();
        course.setSubjectParentId(parentId);
        if (!this.save(course)) throw new GuliException(20001, "课程信息保存失败");
        /*2. 保存描述信息*/
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setDescription(courseInfoVo.getDescription());
        courseDescription.setId(course.getId());
        if (!courseDescriptionService.save(courseDescription)) throw new GuliException(20001, "课程详情信息保存失败");
        return course.getId();
    }

    /**
     * 根据id获取课程信息
     *
     * @param id
     * @return
     */
    @Override
    public CourseInfoVo getCourseInfoFormById(String id) {
        EduCourse course = this.getById(id);
        if (course == null) {
            throw new GuliException(20001, "数据不存在");
        }
        CourseInfoVo courseInfoVo = new CourseInfoVo();
        BeanUtils.copyProperties(course, courseInfoVo);
        EduCourseDescription courseDescription = courseDescriptionService.getById(id);
        if (course != null) {
            courseInfoVo.setDescription(courseDescription.getDescription());
        }
        return courseInfoVo;
    }

    @Override
    public void updateCourseInfoById(CourseInfoVo courseInfoVo) {
        //保存课程基本信息
        EduCourse course = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, course);
        /*获取课程分类父id的信息并且设置*/
        String parentId = subjectService.getById(courseInfoVo.getSubjectId()).getParentId();
        course.setSubjectParentId(parentId);
        boolean resultCourseInfo = this.updateById(course);
        if (!resultCourseInfo) {
            throw new GuliException(20001, "课程信息保存失败");
        }
        //保存课程详情信息
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setDescription(courseInfoVo.getDescription());
        courseDescription.setId(course.getId());
        boolean resultDescription = courseDescriptionService.updateById(courseDescription);
        if (!resultDescription) {
            throw new GuliException(20001, "课程详情信息保存失败");
        }
    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        return baseMapper.getCoursePublishVoById(id);
    }

    @Override
    public boolean publishCourseById(String id) {
        EduCourse course = new EduCourse();
        course.setId(id);
        course.setStatus(EduCourse.COURSE_NORMAL);
        Integer count = baseMapper.updateById(course);
        return null != count && count > 0;
    }

    @Override
    public Map<String, Object> pageQuery(Page<EduCourse> pageParam, CourseQueryVo courseQueryVo) {
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("gmt_create");
        if (courseQueryVo == null) {
            baseMapper.selectPage(pageParam, queryWrapper);
            return null;
        }
        String title = courseQueryVo.getTitle();
        String teacherId = courseQueryVo.getTeacherId();
        String subjectParentId = courseQueryVo.getSubjectParentId();
        String subjectId = courseQueryVo.getSubjectId();
        if (!StringUtils.isEmpty(title)) {
            queryWrapper.like("title", title);
        }
        if (!StringUtils.isEmpty(teacherId)) {
            queryWrapper.eq("teacher_id", teacherId);
        }
        if (!StringUtils.isEmpty(subjectParentId)) {
            queryWrapper.ge("subject_parent_id", subjectParentId);
        }
        if (!StringUtils.isEmpty(subjectId)) {
            queryWrapper.ge("subject_id", subjectId);
        }
        baseMapper.selectPage(pageParam, queryWrapper);
        Map<String, Object> map = new HashMap<String, Object>();
        List<EduCourse> courseList = pageParam.getRecords();
        for (EduCourse course : courseList) {
            course.setCommentCount((long) commentService.count(new QueryWrapper<EduComment>().eq("course_id", course.getId()).eq("is_deleted", 0)));
        }
        map.put("total", pageParam.getTotal());
        map.put("rows", courseList);
        return map;
    }

    @Override
    public boolean removeCourseById(String id) {
        //根据id删除所有小节
        videoService.removeByCourseId(id);
        //根据id删除所有章节
        chapterService.removeByCourseId(id);
        // 删除当前课程的描述
        courseDescriptionService.removeById(id);
        // 删除当前课程
        int result = baseMapper.deleteById(id);
        return result > 0;
    }

    @Override
    public List<EduCourse> selectByTeacherId(String id) {
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<EduCourse>();
        queryWrapper.eq("teacher_id", id);
        //按照最后更新时间倒序排列
        queryWrapper.orderByDesc("gmt_modified");
        List<EduCourse> courses = baseMapper.selectList(queryWrapper);
        for (EduCourse course : courses) {
            course.setCommentCount((long) commentService.count(new QueryWrapper<EduComment>().eq("course_id", course.getId()).eq("is_deleted", 0)));
        }
        return courses;
    }

    @Override
    public Map<String, Object> pageListFront(Page<EduCourse> pageParam, CourseQueryVo courseQuery) {
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(courseQuery.getTitle())) {
            queryWrapper.like("title", courseQuery.getTitle());
        }
        if (!StringUtils.isEmpty(courseQuery.getSubjectParentId())) {
            queryWrapper.eq("subject_parent_id", courseQuery.getSubjectParentId());
        }
        if (!StringUtils.isEmpty(courseQuery.getSubjectId())) {
            queryWrapper.eq("subject_id", courseQuery.getSubjectId());
        }
        if (!StringUtils.isEmpty(courseQuery.getCommentCountSort())) {
            queryWrapper.orderByDesc("comment_count");
        }
        if (!StringUtils.isEmpty(courseQuery.getGmtCreateSort())) {
            queryWrapper.orderByDesc("gmt_create");
        }
        if (!StringUtils.isEmpty(courseQuery.getViewCountSort())) {
            queryWrapper.orderByDesc("view_count");
        }
        baseMapper.selectPage(pageParam, queryWrapper);
        List<EduCourse> records = pageParam.getRecords();
        /*统计评论数*/
        for (EduCourse course : records) {
            course.setCommentCount((long) commentService.count(new QueryWrapper<EduComment>().eq("course_id", course.getId()).eq("is_deleted", 0)));
        }
        long current = pageParam.getCurrent();
        long pages = pageParam.getPages();
        long size = pageParam.getSize();
        long total = pageParam.getTotal();
        boolean hasNext = pageParam.hasNext();
        boolean hasPrevious = pageParam.hasPrevious();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("items", records);
        map.put("current", current);
        map.put("pages", pages);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("hasPrevious", hasPrevious);
        return map;
    }

    @Override
    public CourseFrontVo selectInfoWebById(String id) {
        this.updatePageViewCount(id);
        return baseMapper.selectInfoWebById(id);
    }

    @Override
    public void updatePageViewCount(String id) {
        EduCourse course = baseMapper.selectById(id);
        course.setViewCount(course.getViewCount() + 1);
        baseMapper.updateById(course);
    }

    @Override
    public List<EduCourse> selectHot8Courses() {
        List<EduCourse> courseList = baseMapper.selectHot8Courses();
        for (EduCourse course : courseList) {
            course.setCommentCount((long) commentService.count(new QueryWrapper<EduComment>().eq("course_id", course.getId()).eq("is_deleted", 0)));
        }
        return courseList;
    }

    @Override
    public Map<String, Object> collectedPageListFront(Page<EduCourse> pageParam, CourseQueryVo courseQuery, String memberId) {
        List<String> courseIds = courseCollectService.getCourseIdsByMemberId(memberId);
        if (courseIds.size() == 0) courseIds.add("-1");
        QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(courseQuery.getTitle())) {
            queryWrapper.like("title", courseQuery.getTitle());
        }
        if (!StringUtils.isEmpty(courseQuery.getSubjectParentId())) {
            queryWrapper.eq("subject_parent_id", courseQuery.getSubjectParentId());
        }
        if (!StringUtils.isEmpty(courseQuery.getSubjectId())) {
            queryWrapper.eq("subject_id", courseQuery.getSubjectId());
        }
        if (!StringUtils.isEmpty(courseQuery.getCommentCountSort())) {
            queryWrapper.orderByDesc("comment_count");
        }
        if (!StringUtils.isEmpty(courseQuery.getGmtCreateSort())) {
            queryWrapper.orderByDesc("gmt_create");
        }
        if (!StringUtils.isEmpty(courseQuery.getViewCountSort())) {
            queryWrapper.orderByDesc("view_count");
        }
        /*选出被收藏的课程*/
        queryWrapper.in("id", courseIds);
        baseMapper.selectPage(pageParam, queryWrapper);
        List<EduCourse> records = pageParam.getRecords();
        /*统计评论数*/
        for (EduCourse course : records) {
            course.setCommentCount((long) commentService.count(new QueryWrapper<EduComment>().eq("course_id", course.getId()).eq("is_deleted", 0)));
        }
        long current = pageParam.getCurrent();
        long pages = pageParam.getPages();
        long size = pageParam.getSize();
        long total = pageParam.getTotal();
        boolean hasNext = pageParam.hasNext();
        boolean hasPrevious = pageParam.hasPrevious();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("items", records);
        map.put("current", current);
        map.put("pages", pages);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("hasPrevious", hasPrevious);
        return map;
    }

    @Override
    public void addCommentCount(String courseId) {
        // 课程评论+1
        EduCourse course = baseMapper.selectById(courseId);
        course.setCommentCount(course.getCommentCount() + 1);
        baseMapper.updateById(course);
    }

    @Override
    public void subCommentCount(String courseId) {
        // 课程评论+1
        EduCourse course = baseMapper.selectById(courseId);
        course.setCommentCount(course.getCommentCount() - 1 < 0 ? 0 : course.getCommentCount() - 1);
        baseMapper.updateById(course);
    }
}
